﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Alexinea.Autofac.Extensions.DependencyInjection;
using Autofac;
using AutoMapper;
using BestTrader.Cms.Core.Options;
using BestTrader.Cms.IServices;
using BestTrader.Cms.Repository.SqlServer;
using BestTrader.Cms.RmmfSoftServices;
using BestTrader.Cms.Services;
using Hangfire;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using NLog.Extensions.Logging;
using NLog.Web;

namespace BestTrader.Cms.Hangfire
{
    public class Startup
    {
        public IConfiguration Configuration { get; }

        public Startup(IConfiguration configuration, IHostingEnvironment env)
        {
            env.ConfigureNLog("Nlog.config");
            Configuration = configuration;
        }

        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public IServiceProvider ConfigureServices(IServiceCollection services)
        {
            #region Config

            services.Configure<DbOption>("BT.TEST", Configuration.GetSection("DbOption"));
            services.Configure<QiniuOption>("QINIU", Configuration.GetSection("QiniuOption"));
            services.Configure<SystemBankOption>("SYS.BANK", Configuration.GetSection("SystemBankOption"));
            services.Configure<YunpayOption>("YUNPAY", Configuration.GetSection("YunpayOption"));
            services.Configure<RmmsoftOption>("RMMSOFT", Configuration.GetSection("RmmsoftOption"));
            var hfOption = Configuration.GetSection("HangfireOption").Get<HangfireOption>();

            #endregion

            services.AddHangfire(config => {
                config.UseSqlServerStorage(hfOption.ConnectionString);
            });

            services.AddHttpClient<YunPayClientService>();

            #region AutoMapper

            services.AddAutoMapper();   // DI了AutoMapper中需要用到的服务，其中包括AutoMapper的配置类 Profile 

            #endregion

            #region AutoFac

            //services.AddScoped<ITimerService, TimerService>();
            //services.AddScoped<ICheckService, CheckService>();
            //services.AddScoped<IStartService, StartService>();

            //[Autofac 使用经验](https://www.cnblogs.com/ideacore/p/7532041.html)
            var builder = new ContainerBuilder();
            builder.Populate(services);
            builder.RegisterAssemblyTypes(typeof(ManagerRoleRepository).Assembly)
                   .Where(t => t.Name.EndsWith("Repository"))
                   .InstancePerLifetimeScope()
                   .AsImplementedInterfaces();
            builder.RegisterAssemblyTypes(typeof(ManagerRoleService).Assembly)
                 .Where(t => t.Name.EndsWith("Service"))
                 .InstancePerLifetimeScope()
                 .AsImplementedInterfaces();
            builder.RegisterAssemblyTypes(typeof(RmmfSoftAccountService).Assembly)
                .InstancePerLifetimeScope()
                .Where(t => t.Name.EndsWith("Service"));

            return new AutofacServiceProvider(builder.Build());

            #endregion
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, IServiceProvider serviceProvider, ILoggerFactory loggerFactory)
        {
            GlobalConfiguration.Configuration.UseActivator<MyActivator>(new MyActivator(serviceProvider));
            //GlobalConfiguration.Configuration.UseAutofacActivator(container);

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            //add NLog to ASP.NET Core
            loggerFactory.AddNLog();

            #region Hangfire
            app.UseHangfireServer();
            //app.UseHangfireDashboard();
            app.UseHangfireDashboard("/hangfire", new DashboardOptions()
            {
                Authorization = new[] { new CustomAuthorizeFilter() }
            });

            app.Map("/oneInit", r =>
            {
                r.Run(context =>
                {
                    BackgroundJob.Enqueue<IBatchService>(c => c.RmmfHistoryDealedOrderReportAsync());
                    return context.Response.WriteAsync("ok");
                });
            });

            app.Map("/oneEnManager", r =>
            {
                r.Run(context =>
                {
                    BackgroundJob.Enqueue<IBatchService>(c => c.SyncEnManager());
                    return context.Response.WriteAsync("ok");
                });
            });

            app.Map("/oneRecord", r =>
            {
                r.Run(context =>
                {
                    BackgroundJob.Enqueue<IBatchService>(c => c.GetRebateRecord());
                    return context.Response.WriteAsync("ok");
                });
            });

            //app.Map("/await", r =>
            //{
            //    r.Run(context =>
            //    {

            //        BackgroundJob.Schedule(() => Console.WriteLine($"ASP.NET Core await LineZero{DateTime.Now}"), TimeSpan.FromSeconds(20));
            //        return context.Response.WriteAsync("ok");
            //    });
            //});

            app.Map("/gtinit", r =>
            {
                r.Run(context =>
                {
                    // 任务每分钟执行一次
                    RecurringJob.AddOrUpdate<IBatchService>(c => c.RmmfHistoryDealedOrderReportAsync(), "1 12 * * *");
                    return context.Response.WriteAsync("ok");
                });
            });

            app.Map("/gtrecord", r =>
            {
                r.Run(context =>
                {
                    RecurringJob.AddOrUpdate<IBatchService>(c => c.GetRebateRecord(), "30 12 * * *");
                    return context.Response.WriteAsync("ok");
                });
            });

            //app.Map("/gtpayorder", r =>
            //{
            //    r.Run(context =>
            //    {
            //        // 每5分钟轮一次，不满足要求
            //        //RecurringJob.AddOrUpdate<IBatchService>(c => c.YunPayOrderSync(), "5 * * * *");
            //        RecurringJob.AddOrUpdate<IBatchService>(c => c.YunPayOrderSync(), Cron.MinuteInterval(5));
            //        return context.Response.WriteAsync("ok");
            //    });
            //});
            #endregion

            app.Run(async (context) =>
            {
                await context.Response.WriteAsync("Hello World Hangfire!");
            });
           
        }
    }
}
